package com.penghaisoft.task.controller;

import com.penghaisoft.task.common.NodeEnum;
import com.penghaisoft.task.entity.Result;
import com.penghaisoft.task.entity.RtnObjHollysys;
import com.penghaisoft.task.entity.SPCEquipmentSparkleData;
import com.penghaisoft.task.entity.Value;
import com.penghaisoft.task.feign.client.FpjFeignClient;
import com.penghaisoft.task.service.ISPCEquipmentSparkleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.*;

/**
 * @ClassName 调用和利时接口，获取发泡线数据
 * @Description
 * @Author luo_0
 * @Date 2020/8/17 14:48
 **/
@Component
@Slf4j
public class FpjTaskController {

    @Autowired
    private FpjFeignClient fpjFeignClient;

    @Autowired
    private ISPCEquipmentSparkleService spcEquipmentSparkleService;

//    @Scheduled(cron = "0 0/5 * * * ? ")
    public void scheduledJob() {
        log.info("##########开始处理###########");
//        处理设备编号9010XAXTFP0001，对应 NodeEnum.NodeB1 发泡线
        deal_new("9010XAXTFP0001");
        log.info("9010XAXTFP0001处理完成");
//        处理设备编号9010XAXTFP0002，对应 NodeEnum.NodeB1 发泡线
        deal_new("9010XAXTFP0002");
        log.info("9010XAXTFP0002处理完成");
        log.info("##########结束处理###########");
    }

    private void deal(String equipmentno) {
//        一天的毫秒数3
        long oneDayMillis = 1000 * 60 * 60 * 24;
//        开始时间
        long start = 0L;
//        结束时间
        long end = System.currentTimeMillis();
        SPCEquipmentSparkleData spcEquipmentSparkleData = spcEquipmentSparkleService.selectTop1(equipmentno);
        if (spcEquipmentSparkleData != null) {
            if (spcEquipmentSparkleData.getCollecttime() != null) {
                start = spcEquipmentSparkleData.getCollecttime().getTime();
            }
            log.info(equipmentno + "存在最新一条数据！" + spcEquipmentSparkleData.getCollecttime());
        } else {
            log.info(equipmentno + "不存在数据！");
        }

//        如果当前时间点比数据库的时间点多一天，只查询当前零点至当前时间点的数据
        if (oneDayMillis < (end - start)) {
            start = end - oneDayMillis;
        }

//        log.info("end" + end);
        Map<String, Object> map = new HashMap<String, Object>();
        Map<String, Object> detailMap = new HashMap<String, Object>();
        detailMap.put("maxSizePerNode", 500);
        detailMap.put("returnBounds", true);
        detailMap.put("startTime", start);
        detailMap.put("endTime", end);

        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        Map<String, Object> nodeMap = new HashMap<String, Object>();

        if ("9010XAXTFP0001".equals(equipmentno)) {
            for (NodeEnum.NodeB1 tmp : NodeEnum.NodeB1.values()) {
                nodeMap = new HashMap<String, Object>();
                nodeMap.put("continuationPoint", "");
                nodeMap.put("id", tmp.getTag());
                nodeMap.put("namespace", tmp.getNameSpace());
                list.add(nodeMap);
            }
        } else if ("9010XAXTFP0002".equals(equipmentno)) {
            for (NodeEnum.NodeB2 tmp : NodeEnum.NodeB2.values()) {
                nodeMap = new HashMap<String, Object>();
                nodeMap.put("continuationPoint", "");
                nodeMap.put("id", tmp.getTag());
                nodeMap.put("namespace", tmp.getNameSpace());
                list.add(nodeMap);
            }
        }

        map.put("detail", detailMap);
        map.put("nodes", list);

        RtnObjHollysys rtnOb = fpjFeignClient.getHistoryValue(map);

        if (rtnOb != null && "0".equals(rtnOb.getCode())) {
            List<Result> results = rtnOb.getResults();
            if (results != null && !results.isEmpty()) {
                if (results.size() != NodeEnum.NodeB1.values().length) {
                    log.info("和利时返回数据数量不是" + NodeEnum.NodeB1.values().length + "个，而是" + results.size() + "个。");
                    return;
                }

                String compare = "";
                List<SPCEquipmentSparkleData> insertList = new ArrayList<SPCEquipmentSparkleData>();
                Result rt0 = results.get(0);
//                log.info("rt0.getHistoryData():" + rt0.getHistoryData());
                for (Value value : rt0.getHistoryData()) {
                    SPCEquipmentSparkleData tmp = new SPCEquipmentSparkleData();
                    tmp.setDataId(UUID.randomUUID().toString());
                    tmp.setEquipmentno(equipmentno);
                    tmp.setCollecttime(new Date(value.getT()));

                    int i = 0;
                    long time = value.getT();
                    StringBuffer sb = new StringBuffer();
                    for (NodeEnum.NodeB1 b1 : NodeEnum.NodeB1.values()) {
                        Result rt = results.get(i);
                        for (Value v : rt.getHistoryData()) {
                            if ((v.getT() - time) >= -1000 && (v.getT() - time) <= 1000) {
                                Class cl = tmp.getClass();
                                String fieldName = b1.getAttr();
                                try {
                                    Field field = cl.getDeclaredField(fieldName);
                                    field.setAccessible(true);
                                    field.set(tmp, new BigDecimal(v.getV()));
                                    sb.append(String.valueOf(v.getV()));
                                } catch (Exception e) {
//                                    e.printStackTrace();
                                }
                                break;
                            }
                        }

                        i++;
                    }

//                    自身数据去重【相邻两条数据不重复】
                    if (!compare.equals(sb.toString())) {
                        Boolean flag = false;
                        for (NodeEnum.NodeB1 b1 : NodeEnum.NodeB1.values()) {
                            Class cl = tmp.getClass();
                            String fieldName = b1.getAttr();
                            try {
                                Field field = cl.getDeclaredField(fieldName);
                                field.setAccessible(true);
                                if (field.get(tmp) == null) {
                                    flag = true;
                                    break;
                                }
                            } catch (Exception e) {
                            }
                        }

//                        flag = false;
                        if (!flag) {
                            insertList.add(tmp);
                            compare = sb.toString();
                        }
                    }

//                    if (!compare.equals(sb.toString())) {
//                        insertList.add(tmp);
//                        compare = sb.toString();
//                    }
                }

                log.info("待插入" + insertList.size() + "条数据！");

//                跟数据库存在的数据比对是否重复【取出来的数据跟数据库的最新一条进行比对】
                if (insertList != null && !insertList.isEmpty()) {
                    SPCEquipmentSparkleData compareData = insertList.get(0);
//                    数据库不存在数据
                    if (spcEquipmentSparkleData == null) {
                        log.info("数据库不存在历史数据！");
//                        暂时不考虑性能了，一条一条的插入吧【取数时效要求不高】
                        for (SPCEquipmentSparkleData tmp : insertList) {
                            spcEquipmentSparkleService.insertSelective(tmp);
                        }
                        log.info("#插入" + insertList.size() + "条数据！");
                    } else {
                        log.info("数据库存在历史数据！");
                        Class c1 = compareData.getClass();
                        Class c2 = spcEquipmentSparkleData.getClass();
                        Field[] fields = c1.getDeclaredFields();
                        Boolean flag_same = true;
                        if (fields != null) {
                            for (Field f : fields) {
                                try {
                                    if ("dataId".equals(f.getName()) || "collecttime".equals(f.getName())) {
                                        continue;
                                    }
                                    Field field1 = c1.getDeclaredField(f.getName());
                                    field1.setAccessible(true);
                                    Field field2 = c2.getDeclaredField(f.getName());
                                    field2.setAccessible(true);
//                                    log.info("#" + field1.get(compareData).toString() + "#" + field2.get(spcEquipmentSparkleData).toString());
                                    if (!field1.get(compareData).toString().split(".")[0].equals(field2.get(spcEquipmentSparkleData).toString().split(".")[0])) {
                                        flag_same = false;
                                        break;
                                    }
                                } catch (Exception e) {
//                                    e.printStackTrace();
                                }
                            }
                        }

                        if (flag_same) {
                            insertList.remove(compareData);
                        }

                        log.info("与数据库历史最后一条数据比较后，待插入" + insertList.size() + "条数据！");

                        if (insertList != null && !insertList.isEmpty()) {
                            for (SPCEquipmentSparkleData tmp : insertList) {
                                spcEquipmentSparkleService.insertSelective(tmp);
                            }

                            log.info("插入" + insertList.size() + "条数据！");
                        }
                    }
                }
            }
        } else {
            log.info("和利时返回失败状态: " + rtnOb);
        }

        long t2 = System.currentTimeMillis();
//        log.info("feign返回结果: " + rtnOb);
        log.info("feign耗时：" + (t2 - end));
    }

    /**
     * @return
     * @Description 10分钟间隔的数据全部插入
     * @Author luot
     * @Date 2020/8/31 15:19
     * @Param
     **/
    private void deal_new(String equipmentno) {
//        一天的毫秒数3
        long oneDayMillis = 1000 * 60 * 60 * 24;
//        开始时间
        long start = 0L;
//        结束时间
        long end = System.currentTimeMillis();
        SPCEquipmentSparkleData spcEquipmentSparkleData = spcEquipmentSparkleService.selectTop1(equipmentno);
        if (spcEquipmentSparkleData != null) {
            if (spcEquipmentSparkleData.getCollecttime() != null) {
                start = spcEquipmentSparkleData.getCollecttime().getTime();
            }
            log.info(equipmentno + "存在最新一条数据！" + spcEquipmentSparkleData.getCollecttime());
        } else {
            log.info(equipmentno + "不存在数据！");
        }

//        如果当前时间点比数据库的时间点多一天，只查询当前零点至当前时间点的数据
        if (oneDayMillis < (end - start)) {
            start = end - oneDayMillis;
        }

//        log.info("end" + end);
        Map<String, Object> map = new HashMap<String, Object>();
        Map<String, Object> detailMap = new HashMap<String, Object>();
        detailMap.put("maxSizePerNode", 500);
        detailMap.put("returnBounds", true);
        detailMap.put("startTime", start);
        detailMap.put("endTime", end);

        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        Map<String, Object> nodeMap = new HashMap<String, Object>();

        if ("9010XAXTFP0001".equals(equipmentno)) {
            for (NodeEnum.NodeB1 tmp : NodeEnum.NodeB1.values()) {
                nodeMap = new HashMap<String, Object>();
                nodeMap.put("continuationPoint", "");
                nodeMap.put("id", tmp.getTag());
                nodeMap.put("namespace", tmp.getNameSpace());
                list.add(nodeMap);
            }
        } else if ("9010XAXTFP0002".equals(equipmentno)) {
            for (NodeEnum.NodeB2 tmp : NodeEnum.NodeB2.values()) {
                nodeMap = new HashMap<String, Object>();
                nodeMap.put("continuationPoint", "");
                nodeMap.put("id", tmp.getTag());
                nodeMap.put("namespace", tmp.getNameSpace());
                list.add(nodeMap);
            }
        }

        map.put("detail", detailMap);
        map.put("nodes", list);

        RtnObjHollysys rtnOb = fpjFeignClient.getHistoryValue(map);

        if (rtnOb != null && "0".equals(rtnOb.getCode())) {
            List<Result> results = rtnOb.getResults();
            if (results != null && !results.isEmpty()) {
                if (results.size() != NodeEnum.NodeB1.values().length) {
                    log.info("和利时返回数据数量不是" + NodeEnum.NodeB1.values().length + "个，而是" + results.size() + "个。");
                    return;
                }

                String compare = "";
                List<SPCEquipmentSparkleData> insertList = new ArrayList<SPCEquipmentSparkleData>();
                Result rt0 = results.get(0);
//                log.info("rt0.getHistoryData():" + rt0.getHistoryData());
                for (Value value : rt0.getHistoryData()) {
                    SPCEquipmentSparkleData tmp = new SPCEquipmentSparkleData();
                    tmp.setDataId(UUID.randomUUID().toString());
                    tmp.setEquipmentno(equipmentno);
                    tmp.setCollecttime(new Date(value.getT()));

                    int i = 0;
                    long time = value.getT();
                    StringBuffer sb = new StringBuffer();
                    for (NodeEnum.NodeB1 b1 : NodeEnum.NodeB1.values()) {
                        Result rt = results.get(i);
                        for (Value v : rt.getHistoryData()) {
                            if ((v.getT() - time) >= -1000 && (v.getT() - time) <= 1000) {
                                Class cl = tmp.getClass();
                                String fieldName = b1.getAttr();
                                try {
                                    Field field = cl.getDeclaredField(fieldName);
                                    field.setAccessible(true);
                                    field.set(tmp, new BigDecimal(v.getV()));
                                    sb.append(String.valueOf(v.getV()));
                                } catch (Exception e) {
//                                    e.printStackTrace();
                                }
                                break;
                            }
                        }

                        i++;
                    }

                    insertList.add(tmp);
                }

                log.info("待插入" + insertList.size() + "条数据！");

                if (insertList != null && !insertList.isEmpty()) {
                    for (SPCEquipmentSparkleData tmp : insertList) {
                        spcEquipmentSparkleService.insertSelective(tmp);
                    }

                    log.info("插入" + insertList.size() + "条数据！");
                }
            } else {
                log.info("和利时返回失败状态: " + rtnOb);
            }

            long t2 = System.currentTimeMillis();
//        log.info("feign返回结果: " + rtnOb);
            log.info("feign耗时：" + (t2 - end));
        }
    }
}
